package everyday;

import cn.hutool.core.util.StrUtil;
import org.apache.commons.compress.utils.Sets;
import org.junit.jupiter.api.Test;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 字符串相关操作
 *
 * @author gaojie
 * @date 2022-01-19
 */
class StringOperation {

    private static final Random RANDOM = new Random();

    public static void main(String[] args) {
        for (int i = 0; i < 100; i++) {
            System.out.println(RANDOM.nextInt(6) + 1);
        }
    }

    @Test
    void testSubString2() {
        String diskFile = "123_aaa_bbb";
        String substring = diskFile.substring(0, diskFile.indexOf("_"));
        System.out.println(substring);
        System.out.println(diskFile.substring(diskFile.lastIndexOf("_") + 1));
        System.out.println(diskFile.replace(diskFile.substring(diskFile.lastIndexOf("_") + 1), "default"));
        final String subBefore = StrUtil.subBefore(diskFile, "_", false);
        System.out.println(subBefore);
    }

    /**
     * 根据 class 全类名，找到对应的 beanName
     */
    @Test
    void classFullName2beanName() {
        String classFullName = "com.gaojie.UserService";
        final String className = classFullName.substring(classFullName.lastIndexOf(".") + 1);
        final char[] chars = className.toCharArray();
        chars[0] += 32;
        System.out.println(String.valueOf(chars));
    }

    @Test
    void removeSuffix() {
        String str = "aaa.txt";
        System.out.println(str.substring(0, str.indexOf(".")));
    }

    /**
     * 将字符串转换成字符数组
     */
    @Test
    void testString2Char() {
        String str = "abc";
        for (char c : str.toCharArray()) {
            System.out.println(c);
        }
    }

    @Test
    void testAddPrefix() {
        String prefix = "cc.";
        String filed = "active_time";
        addPrefix(prefix, filed);
    }

    /**
     * 给字符串添加前缀
     */
    private void addPrefix(String prefix, String filed) {
        if (!filed.startsWith(prefix)) {
            String format = String.format("%s%s", prefix, filed);
            System.out.println(format);
        }
    }

    /**
     * 根据文件 path，通过最后一个小数点的位置，找到文件后缀名，然后对后缀做操作
     */
    @Test
    void testIndexOf() {
        String path = "D:\\lls\\gaojie\\Desktop\\图片资源\\20220104\\zip\\Git.zip";
        int lastPointIndex = path.lastIndexOf("."); // 最后一个小数点的下标
        String dirPath = path.substring(0, lastPointIndex);
        String suffix = path.substring(lastPointIndex);
        System.out.printf("文件夹地址：%s%n", dirPath);
        System.out.printf("文件后缀：%s%n", suffix);

        for (int i = 1; i < 15; i++) {
            String replace = i < 10 ? String.format("0%d", i) : i + "";
            String newSuffix = suffix.replace("ip", replace);
            String newPath = String.format("%s%s", dirPath, newSuffix);
            System.out.printf("新地址：%s%n", newPath);
        }
    }

    /**
     * 找出 path 集合中，文件名相同的 path，给文件名标记后缀
     */
    @Test
    void testMarkRepeat() {
        ArrayList<String> list = new ArrayList<>();
        list.add("/data/user/aaa.txt");
        list.add("/data/user/bbb.txt");
        list.add("/data/user/aaa.txt");
        list.add("/data/user/ccc.txt");
        list.add("/data/user/aaa.txt");
        List<String> newList = getFileNames(list);
        newList.forEach(System.out::println);
    }

    /**
     * 根据文件地址集合，获取文件名称集合，遇到重复名称，自动标记下标，避免压缩时报错
     */
    private List<String> getFileNames(List<String> filePaths) {

        // 1.根据文件地址集合，获取文件名称集合
        List<String> fileNames = filePaths.stream().map(this::getFileName).collect(Collectors.toList());

        // 2.统计每个名称的个数
        HashMap<String, Integer> nameCountMap = new HashMap<>();
        fileNames.forEach(name -> nameCountMap.compute(name, (k, v) -> v == null ? 1 : v + 1));

        // 3.如果两个集合的长度不一样，则表示出现了重复的文件名，就需要重命名，不然压缩时会报错
        int size = fileNames.size();
        if (nameCountMap.size() != size) {

            // 3.1.倒叙遍历，按照从前往后添加下标
            for (int i = size - 1; i >= 0; i--) {
                String name = fileNames.get(i);
                int finalI = i;
                nameCountMap.computeIfPresent(name, (k, v) -> {
                    if (v > 1) {
                        // 3.2.v 大于 1，表示数量不只1个，则添加下标
                        fileNames.set(finalI, nameAddSuffix(name, v));
                    }
                    return v - 1;
                });
            }
        }
        return fileNames;
    }

    /**
     * 给文件名，添加后缀
     *
     * @param name   文件名
     * @param suffix 后缀
     */
    private String nameAddSuffix(String name, int suffix) {
        int i = name.indexOf(".");
        return String.format("%s_%d%s", name.substring(0, i), suffix, name.substring(i));
    }

    /**
     * 根据文件路径获取文件名
     */
    String getFileName(String pathPath) {
        return pathPath.substring(pathPath.lastIndexOf("/") + 1);
    }

    @Test
    void testLength() {
        String res_start = "<ns:return>";
        String res_end = "</ns:return>";
        String str = "<?xml version='1.0' encoding='UTF-8'?>\n" +
                "<soapenv:Envelope xmlns:soapenv=\"http://www.w3.org/2003/05/soap-envelope\">\n" +
                "    <soapenv:Body>\n" +
                "        <ns:discountSyncResponse xmlns:ns=\"http://webserver.hq.erp.hibernate.byttersoft.com\">\n" +
                "            <ns:return>{\"id\":\"CD-590758400007520230309000054894\",\"message\":\"流通介质不能为空;流水状态不能为空;处理标记不能为空;业务编号不能为空;贴现不能为空;\",\"status\":\"F\"}</ns:return>\n" +
                "        </ns:discountSyncResponse>\n" +
                "    </soapenv:Body>\n" +
                "</soapenv:Envelope>";
        final int start = str.indexOf(res_start) + res_start.length();
        final int end = str.indexOf(res_end);
        final String substring = str.substring(start, end);
        System.out.println(substring);
        final String subBetween = StrUtil.subBetween(str, res_start, res_end);
        System.out.println(subBetween);
    }

    /**
     * 集合转字符串，自定义分隔符
     */
    @Test
    void test01() {
        final HashSet<String> set = Sets.newHashSet("AA", "BB");
        final String collect = String.join("；", set);
        System.out.println(collect);
    }

    /**
     * HuTool工具类方法【StrUtil.containsAny】测试
     * 结果：相当于批量 contain，只有有一个符合，则返回true
     */
    @Test
    void test02() {
        final boolean b = StrUtil.containsAny("sys-web/user/listPage", "list", "page");
        System.out.println(b);
    }

    /**
     * 判断 string.format() 方法，入参如果为null，是什么样子
     * 结果：null会直接当做字符串输出
     */
    @Test
    void test03() {
        final String haha = String.format("%s-%s", "haha", null);
        System.out.println(haha);
    }

    /**
     * 字符串转char，char转字符串，char比较
     */
    @Test
    void test04() {
        String str = "123abcDEF";
        final char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            final char c = chars[i];

            // 如果是字母，则进行转换，否则不做处理
            if (c >= 65 && c <= 90) {
                // 大写字母：转成小写再往后移一位
                if (c == 90) {
                    chars[i] = 97;
                } else {
                    chars[i] += 33;
                }
            } else if (c >= 97 && c <= 122) {
                // 小写字母转换成数字
                if (c <= 99) {
                    chars[i] = '2';
                } else if (c <= 102) {
                    chars[i] = '3';
                } else if (c <= 105) {
                    chars[i] = '4';
                } else if (c <= 108) {
                    chars[i] = '5';
                } else if (c <= 111) {
                    chars[i] = '6';
                } else if (c <= 114) {
                    chars[i] = '7';
                } else if (c <= 117) {
                    chars[i] = '8';
                } else {
                    chars[i] = '9';
                }
            }
        }
        System.out.println(chars);
    }

    /**
     * 测试去空格方法
     */
    @Test
    void test05() {
        String str = " a a bb .png";
        final String trim = str.trim();
        System.out.println(String.format("[%s]", str));
        System.out.println(String.format("[%s]", trim));
        System.out.println(String.format("[%s]", str.replace(" ", "")));
        System.out.println(String.format("[%s]", str.replaceAll(" ", "")));
    }

    /**
     * 测试去斜杠方法
     */
    @Test
    void test06() {
        String str = " a a /bb .png";
        System.out.println(String.format("[%s]", str));
        System.out.println(String.format("[%s]", str.replace(StrUtil.SLASH, StrUtil.EMPTY)));
    }

    /**
     * 测试时间字符串格式化，使用【replaceAll】正则方式替换
     */
    @Test
    void test07() {
        String dateStr1 = "2024-09-10";
        String dateStr2 = "2024.09.10";
        String dateStr3 = "2024/09/10";
        String dateStr4 = "20240910";
        String dateStr5 = "2024年09月10日";
        String dateStr6 = "2024-09-10 12:12:12";
        replaceDate(dateStr1);
        replaceDate(dateStr2);
        replaceDate(dateStr3);
        replaceDate(dateStr4);
        replaceDate(dateStr5);
        replaceDate(dateStr6);
    }

    /**
     * 替换时间上面的符号
     */
    private String replaceDate(String str) {
        final String replaceAll = str.replaceAll("[-./: 年月日时分秒]", StrUtil.EMPTY);
        System.out.printf("替换前【%s】替换后【%s】%n", str, replaceAll);
        return replaceAll;
    }

    /**
     * 测试 String 的 length() 方法，返回长度是否跟数据类型有关
     * 结论：和类型无关，都是直接计算
     */
    @Test
    void test08() {
        String str1 = "123";
        String str2 = "ABC";
        String str3 = "你我他";
        String str4 = "123ABC你我他";
        System.out.println(str1.length());
        System.out.println(str2.length());
        System.out.println(str3.length());
        System.out.println(str4.length());
    }

    /**
     * 统计字符串的字节长度
     */
    @Test
    void test09() {
        String str = "80何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲何坤莲莲何坤莲何坤莲莲何坤莲何坤莲何坤莲莲何坤莲何坤莲莲何坤莲莲.pdf";
        System.out.println(str.getBytes().length);
    }

    /**
     * 使用 String 的 substring() 方法，切割年月日时分秒
     */
    @Test
    void test10() {
        String yyyyMMddHHmmss = "20241203151515";
        System.out.println(yyyyMMddHHmmss.substring(0, 8));
        System.out.println(yyyyMMddHHmmss.substring(8));
    }

    /**
     * 使用String.format方法时，若需要输出[%]，需要写[%%]转义，否则就会报错
     */
    @Test
    void test11() {
        String tableTitle = "<tr><td>资产编号</td><td>付款方</td><td>待兑付金额(元）</td></tr>";
        String tableContent = "<tr><td>YSZC2023124463</td><td>小米科技有限责任公司</td><td>3300.5</td></tr><tr><td>YSZC2023124444</td><td>小米科技有限责任公司</td><td>2340.67</td></tr><tr><td>YSZC2024014513</td><td>小米科技有限责任公司</td><td>12340.67</td></tr><tr><td>YSZC2023124498</td><td>小米科技有限责任公司</td><td>12340.67</td></tr><tr><td>YSZC2023124468</td><td>小米科技有限责任公司</td><td>12340.67</td></tr><tr><td>YSZC2024014551</td><td>中交一公局子公司</td><td>4563.59</td></tr><tr><td>YSZC2023124503</td><td>小米科技有限责任公司</td><td>4731.5</td></tr><tr><td>YSZC2023124458</td><td>小米科技有限责任公司</td><td>12340.67</td></tr><tr><td>YSZC2024116700</td><td>东丰县盛源苗木繁育专业合作社</td><td>2008</td></tr><tr><td>YSZC2023124473</td><td>小米科技有限责任公司</td><td>1800.5</td></tr><tr><td>YSZC2023124483</td><td>小米科技有限责任公司</td><td>12340.67</td></tr>";
        String html = String.format("<!DOCTYPE html><html lang=\"en\"><head><meta charset=\"UTF-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"><style>table {border: solid 5px #00ccff;}tr{height: 50px;width: 100%%;border: solid 1px #000;background-color: #6e9696a1;}tr:hover{background-color: #ff060670;}td:hover{background-color: chocolate;color: #0eebb3dc;}</style></head><body><table border=\"1px\" width=\"300px\" height=\"300px\">%s</table></body></html>", tableTitle + tableContent);
        System.out.println(html);
    }
}